package cn.fayang.basic.service.impl;

import cn.fayang.basic.constants.BaseConstant;
import cn.fayang.basic.dto.RegisterDto;
import cn.fayang.basic.exception.BusinessException;
import cn.fayang.basic.service.IVerifyCodeService;
import cn.fayang.basic.util.StrUtils;
import cn.fayang.basic.util.VerifyCodeUtils;
import cn.fayang.user.domain.User;
import cn.fayang.user.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;
@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserMapper userMapper;

    /**
     * 获取图形验证码
     * @param key
     * @return
     */
    @Override
    public String imageCode(String key) {
        String code = StrUtils.getComplexRandomString(4);
        redisTemplate.opsForValue().set(key,code,5, TimeUnit.MINUTES);
        return VerifyCodeUtils.VerifyCode(100,40,code);
    }

    /**
     * 发送短信验证码
     * @param dto
     */
    @Override
    public void smsCode(RegisterDto dto) {
        String imageCodeKey = dto.getImageCodeKey();
        String imageCodeValue = dto.getImageCodeValue();
        String phone = dto.getPhone();
        //判断参数是否为空,如果为空抛出异常
        ///*一：校验
        //*  1.空校验
        if(StringUtils.isEmpty(imageCodeKey)|| StringUtils.isEmpty(imageCodeValue)
                ||StringUtils.isEmpty(phone)){
            throw new BusinessException("参数不能为空");
        }
        // 2.校验图形验证码，根据imageCodeKey从redis获取图形验证码
        Object imgsCodeTmp = redisTemplate.opsForValue().get(imageCodeKey);
        //*   。获取不到 图形验证码过期，重新获取
        if(imgsCodeTmp == null){
            new BusinessException("图形验证码已过期,请从新填写");
        }
        //前端传回的图形验证码和Redis中的值对比,不相同抛出异常
        if(!imgsCodeTmp.toString().equalsIgnoreCase(imageCodeValue)){
            new BusinessException("图形验证码不正确,请从新填写");
        }
        //从数据库查user判断是否注册过
        User user = userMapper.loadByPhone(phone);
        //注册过直接登录
        if(user != null ){
            new BusinessException("该手机号已经注册,请直接登录");
        }
        //* 二：短信验证码逻辑
        String key = BaseConstant.RegisterConstants.REGISTER_SMS_PREFIX + phone;
        Object smsCodeTmp = redisTemplate.opsForValue().get(key);
        //*  1.根据手机号拼接key，159:register，从redis获取曾今可能发送的短信验证码
        //*   1.1 获取到了
        //*     1.1.1 校验是否过了一分钟重发时间 value  9527:232468742341657213
        String smsCode = "";
        //判断短信验证码是否存在
        if(smsCodeTmp != null){
        //截取value后的时间戳
        Long oldTime = Long.valueOf(smsCodeTmp.toString().split(":")[1]);
        //如果小于前端按钮置灰时间,则是绕过前端直接访问接口
            if(System.currentTimeMillis() - oldTime <= 1*60*1000){
                throw new BusinessException("请勿频繁刷新");
            }
            smsCode = smsCodeTmp.toString().split(":")[0];
        }else {
            //如果不存在从新生成
            smsCode = StrUtils.getComplexRandomString(4);
        }
        String smsCodeValue = smsCode + ":" + System.currentTimeMillis();
        redisTemplate.opsForValue().set(
                key,
                smsCodeValue,
                3,
                TimeUnit.MINUTES
        );

        System.out.println("亲，您的验证码是：" + smsCode + "。请在3分钟内使用！！");
    }


}
